﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


namespace ArkanoidX
{
    static class Utility
    {
        public enum HitBorder
        {
            None,
            Left,
            Right,
            Top,
            Bottom
        }

        public static bool Collide(Vector2 center, float radius, Rectangle rect, out Vector2 hitPoint, out HitBorder hitBorder)
        {
            hitBorder = HitBorder.None;
            hitPoint = default(Vector2);

            // this is a simplified and inacurate algorithm that 
            // detects whether these two shapes collide
            // since you may easily see the case when the ball is somewhere 
            // near the corner of the rectangle
            if (center.X + radius < rect.Left)
                return false;
            if (center.X - radius > rect.Right)
                return false;
            if (center.Y + radius < rect.Top)
                return false;
            if (center.Y - radius > rect.Bottom)
                return false;

            // a simplistic algorithm that works out the point of clash
            // which is always on the boundary of the rectangle
            float dx = center.X - rect.Center.X;
            float dy = center.Y - rect.Center.Y;

            float slope = rect.Width / rect.Height;
            float criterion = Math.Abs(dy) * rect.Width - Math.Abs(dx) * rect.Height;
            if (criterion > 0)
            {   // on the horizontal border
                if (dy > 0)
                {   // lower border
                    float px = rect.Height * 0.5f * dx / dy;
                    hitPoint = new Vector2(rect.Center.X + px, rect.Bottom);
                    hitBorder = HitBorder.Bottom;
                }
                else
                {   // upper border
                    float px = -rect.Height * 0.5f * dx / dy;
                    hitPoint = new Vector2(rect.Center.X + px, rect.Top);
                    hitBorder = HitBorder.Top;
                }
            }
            else
            {   // on the vertical border
                if (dx > 0)
                {   // right border
                    float py = rect.Width * 0.5f * dy / dx;
                    hitPoint = new Vector2(rect.Right, rect.Center.Y + py);
                    hitBorder = HitBorder.Right;
                }
                else
                {   // left border
                    float py = -rect.Width * 0.5f * dy / dx;
                    hitPoint = new Vector2(rect.Left, rect.Center.Y + py);
                    hitBorder = HitBorder.Left;
                }
            }

            return true;
        }
    }
}
